home *** CD-ROM | disk | FTP | other *** search
- /*
- File: EmbedCtr.cpp
-
- Contains: Implementation for ODEmbeddedContainer.
-
- Owned by: Vincent Lo
-
- Copyright: © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <7> 8/13/96 DM 1362809: make sure Close() can be called
- again harmlessly even if an error occurs
- <6> 7/23/96 DH Bug #1371093: Fatal errors should be
- allowed for embedded containers. Approved
- by Bern.
- <5> 6/6/96 jpa T10020: Fixed uninitialized variable
- (ODIText) warning.
- <4> 5/24/96 jpa 1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
- <3> 5/23/96 DH 1344338: Force quit of document when
- dragging 'Bad' file or Container. Turned
- off fatal Bento errors for Open and Create
- container operations. Now Bento just throws
- and the Container Manager can deal with the
- error.
-
- To Do:
- Eliminate shouldMerge in containerID.
- In Progress:
-
- */
-
- #ifndef _QDFIXM_
- #include "QDFixM.h"
- #endif
-
- #ifndef _PLFMDEF_
- #include "PlfmDef.h"
- #endif
-
-
- #define ODEmbeddedContainer_Class_Source
- #define VARIABLE_MACROS
- #include <EmbedCtr.xih>
-
- #ifndef SOM_ODRefCntObject_xh
- #include <RefCtObj.xh>
- #endif
-
- #ifndef SOM_ODStorageSystem_xh
- #include <ODStor.xh>
- #endif
-
- #ifndef _SESSHDR_
- #include "SessHdr.h" // for sessionRoutinesMetahandler
- #endif
-
- #ifndef _EMBEDHDR_
- #include "EmbedHdr.h"
- #endif
-
- #ifndef _TARGTHDR_
- #include "TargtHdr.h"
- #endif
-
- #ifndef __CM_API__
- #include "CMAPI.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _INDHDR_
- #include "IndHdr.h"
- #endif
-
- #ifndef _ODNEW_
- #include "ODNew.h"
- #endif
-
- #ifndef __STRING__
- #include <string.h> // for strlen
- #endif
-
- #ifndef _BENTOSUPPRESS_
- #include <BentoSuppress.h>
- #endif
-
-
- //==============================================================================
- // Constants
- //==============================================================================
- const ODType kODEmbeddedContainerTypeName = "EmbedHdr";
-
- #if ODDebug
- // #define ODDebug_EmbedCtr 1
- #endif
-
- #pragma segment EmbedCtr
-
- //==============================================================================
- // ODEmbeddedContainer
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: GetName
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainerName SOMLINK ODEmbeddedContainerGetName(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetName");
-
- WARN("EmbeddedContainer does not have a name.");
-
- // The following two lines are used to pacify the compiler.
- // They should never be executed.
- ODIText dummy;
- InitIText(&dummy);
- return dummy;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: SetName
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODEmbeddedContainerSetName(ODEmbeddedContainer *somSelf, Environment *ev,
- ODContainerName* name)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","SetName");
-
- // This function is an no-op.
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: AcquireDocument
- //------------------------------------------------------------------------------
-
- SOM_Scope ODDocument* SOMLINK ODEmbeddedContainerAcquireDocument(ODEmbeddedContainer *somSelf, Environment *ev,
- ODDocumentID id)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","AcquireDocument");
-
- ODUnused(id);
-
- return kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: Release
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODEmbeddedContainerRelease(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Release");
-
- ODEmbeddedContainer_parent_ODBentoContainer_Release(somSelf, ev);
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: ~ODEmbeddedContainer
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODEmbeddedContainersomUninit(ODEmbeddedContainer *somSelf)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","somUninit");
-
- #ifdef DebugRefCount
- printf("~ODEmbeddedContainer %x CMContainer %x\n", somSelf, _fContainer);
- fflush(stdout);
- #endif
-
- Environment* ev = somGetGlobalEnvironment ();
-
- // if (_fCMContainer != kODNULL)
- // somSelf->Close(ev);
-
- if (_fHandlers != kODNULL)
- delete _fHandlers;
-
- // Theoretically, we should not delete the ID because they should be able to
- // be reused.
- //
- // ODContainerID id = somSelf->GetID(ev);
- // if (id != kXMPNULL)
- // delete id;
-
- ODEmbeddedContainer_parent_ODBentoContainer_somUninit(somSelf);
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: InitContainer
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODEmbeddedContainerInitContainer(ODEmbeddedContainer *somSelf, Environment *ev,
- ODStorageSystem* storage,
- ODContainerID* id)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","InitContainer");
-
- SOM_TRY
-
- /* Moved from somInit. SOM itself sets fields to zero
- _fCMContainer = kODNULL;
- _fHandlers = kODNULL;
- _fTargetValue = kODNULL;
- */
- _fUseMode = kCMReading;
- _fShouldMerge = kODTrue;
-
- ODEmbeddedContainer_parent_ODBentoContainer_InitContainer(somSelf, ev, storage, id);
-
-
- ODByteArray ba = somSelf->GetID(ev);
- ODEmbeddedContainerID containerID = *((ODEmbeddedContainerID*) ba._buffer);
- // _fShouldMerge = containerID.shouldMerge;
- _fHandlers = new(somSelf->GetHeap(ev)) ODEmbeddedHandlers(somSelf->GetCMSession(ev),
- containerID.cmValue);
- _fHandlers->Initialize();
-
- ODDisposePtr(ba._buffer);
-
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: Create
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODEmbeddedContainerCreate(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Create");
-
- SOM_TRY
-
- if (_fCMContainer == kODNULL) {
-
- CMSession cmSession = somSelf->GetCMSession(ev);
- if (cmSession == kODNULL)
- THROW(kODErrCannotCreateContainer);
-
- // ODType prevObjectName = _fID->GetPrevObjectName();
-
- ODByteArray ba = somSelf->GetID(ev);
- CMValue cmValue = *((CMValue*) ba._buffer);
- ODType prevObjectName = (ODType) CMGetValueRefCon(cmValue);
- ODDisposePtr(ba._buffer);
-
- // Just to be safe, we are calling this even though we may have called this
- // already for some other containers.
- CMSetMetaHandler(cmSession,
- (CMGlobalName) CMTargetHandlersTypeName,
- targetContainerMetahandler);
-
- CMSetMetaHandler(cmSession,
- kODIndirectValueGlobalName,
- IndirectDynamicValueMetahandler);
-
- if (prevObjectName != kODNULL) {
- #if MergeContainersAvailable
- CMValue embeddedValue;
- CMContainer fileContainer;
- CMObject embeddedObject;
- CMProperty embeddedCntProp, targetObjectProp;
- CMType embeddedCntType;
- CMObject prevObject;
-
- _fCMContainer = CMOpenNewContainer(cmSession,
- _fHandlers,
- kODEmbeddedContainerTypeName,
- (CMContainerUseMode) (kCMUpdateTarget+kCMMerging+kCMReuseFreeSpace),
- kCMNextGeneration, kCMDefaultEndian,
- prevObjectName);
-
- if (_fCMContainer == kODNULL)
- THROW(kODErrCannotCreateContainer);
- ODVolatile(embeddedObject);
- ODVolatile(embeddedCntProp);
- ODVolatile(embeddedCntType);
- TRY
- ODSessionMustHaveCMAllocReserve(_fCMContainer);
- embeddedValue = _fHandlers->ReturnParentValueHandler();
- CMGetValueInfo(embeddedValue, &fileContainer, &embeddedObject,
- &embeddedCntProp, &embeddedCntType, kODNULL);
- targetObjectProp = CMRegisterProperty(fileContainer, prevObjectName);
- CMGetValueInfo(embeddedValue, &fileContainer, &embeddedObject,
- &embeddedCntProp, &embeddedCntType, NULL);
- prevObject = CMGetPrevObjectWithProperty(fileContainer, embeddedObject, embeddedCntProp);
- embeddedObject = CMGetPrevObjectWithProperty(fileContainer, embeddedObject, targetObjectProp);
- if (prevObject == embeddedObject)
- CMReleaseObject(prevObject);
- else { /* we suspect this is garbage, check if we should delete it */
- TRY /* if anything fails, garbage object is not deleted, big deal */
- embeddedValue = CMUseValue(prevObject, embeddedCntProp, embeddedCntType);
- CMReleaseValue(embeddedValue);
- if (!CMContainsValidLabel(embeddedValue)) {
- CMReleaseObject(prevObject);
- CMDeleteObject(prevObject);
- }
- else
- CMReleaseObject(prevObject);
- CATCH_ALL
- ENDTRY
- }
- embeddedValue = CMUseValue(embeddedObject, embeddedCntProp, embeddedCntType);
- ODSessionRestoreCMAllocReserve(_fCMContainer);
- CATCH_ALL
- embeddedValue = kODNULL;
- ENDTRY
- _fTargetValue = embeddedValue;
- #else
- _fCMContainer = CMOpenNewContainer(cmSession,
- _fHandlers,
- kODEmbeddedContainerTypeName,
- (CMContainerUseMode) (kCMUpdateTarget),
- kCMNextGeneration, kCMDefaultEndian,
- prevObjectName);
- #endif
- _fUseMode = kCMUpdateTarget;
- ODDisposePtr(prevObjectName);
- CMSetValueRefCon(cmValue, kODNULL);
- }
- else {
- _fCMContainer = CMOpenNewContainer(cmSession,
- _fHandlers,
- kODEmbeddedContainerTypeName,
- (CMContainerUseMode) (kCMWriting),
- kCMNextGeneration, kCMDefaultEndian);
- _fUseMode = kCMWriting;
- }
-
- if (_fCMContainer == kODNULL)
- THROW(kODErrCannotCreateContainer);
-
- }
-
-
- return somSelf;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return (ODContainer*) kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: Open
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODEmbeddedContainerOpen(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Open");
-
- SOM_TRY
-
- if (_fCMContainer == kODNULL) {
-
- CMSession cmSession = somSelf->GetCMSession(ev);
- if (cmSession == kODNULL)
- THROW(kODErrCannotOpenContainer);
-
- // Just to be safe, we are calling this even though we may have called this
- // already for some other containers.
- CMSetMetaHandler(cmSession,
- (CMGlobalName) CMTargetHandlersTypeName,
- targetContainerMetahandler);
-
- CMSetMetaHandler(cmSession,
- kODIndirectValueGlobalName,
- IndirectDynamicValueMetahandler);
-
- _fCMContainer = CMOpenContainer(cmSession,
- _fHandlers,
- kODEmbeddedContainerTypeName,
- (CMContainerUseMode)(kCMReading));
-
- ODSessionRestoreCMAllocReserve(_fCMContainer);
-
- if (_fCMContainer == kODNULL)
- THROW(kODErrCannotOpenContainer);
-
- _fUseMode = kCMReading;
- }
-
- return somSelf;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- return (ODContainer*) kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: Close
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODEmbeddedContainerClose(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Close");
-
- SOM_TRY
-
- if (_fCMContainer != kODNULL) {
-
- ODSessionMustHaveCMAllocReserve(_fCMContainer);
- #if MergeContainersAvailable
- if (_fShouldMerge && (_fUseMode != kCMReading)) {
- #ifdef ODDebug_EmbedCtr
- somPrintf("Closing EmbedCtr: Merge\n");
- #endif
- CMMergeContainer(_fCMContainer, _fTargetValue);
- }
- else {
- #ifdef ODDebug_EmbedCtr
- somPrintf("Closing EmbedCtr: Close\n");
- #endif
- CMCloseContainer(_fCMContainer);
- }
- if (_fTargetValue) {
- CMReleaseValue(_fTargetValue);
- _fTargetValue = kODNULL;
- }
-
- #else
- CMCloseContainer(_fCMContainer);
- #endif
- _fCMContainer = kODNULL;
- }
-
- return somSelf;
-
- SOM_CATCH_ALL
-
- // Ensure that calling this function twice is harmless.
- _fCMContainer = kODNULL;
-
- SOM_ENDTRY
- return (ODContainer*) kODNULL;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: Purge
- //------------------------------------------------------------------------------
-
- SOM_Scope ODSize SOMLINK ODEmbeddedContainerPurge(ODEmbeddedContainer *somSelf, Environment *ev,
- ODSize size)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Purge");
-
- ODULong runningTotal = 0; ODVolatile( runningTotal );
-
- SOM_TRY
- runningTotal = ODEmbeddedContainer_parent_ODBentoContainer_Purge(somSelf, ev, size);
- SOM_CATCH_ALL
- WARN("Error %ld trying to purge in CMDraftPurge",ErrorCode());
- SetErrorCode(kODNoError); // dh - Eat the exception; Purge should not
- // propagate it because clients function
- // fine whether memory was purged or not.
- SOM_ENDTRY
-
- return runningTotal;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: ReleaseDocument
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODEmbeddedContainerReleaseDocument(ODEmbeddedContainer *somSelf, Environment *ev,
- ODDocument* document)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","ReleaseDocument");
-
- ODUnused(document);
-
- return somSelf;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: Abort
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODEmbeddedContainerAbort(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Abort");
-
- // SOM_CATCH return (ODContainer*) kODNULL;
-
- CMSize valueSize;
-
- if (_fCMContainer != kODNULL) {
- if (_fUseMode != kCMReading) {
- SOM_TRY
- ODSessionMustHaveCMAllocReserve(_fCMContainer);
- CMAbortContainer(_fCMContainer);
-
- // Trunc the value as Bento does not do it for us.
- ODByteArray ba = somSelf->GetID(ev);
- CMValue value = *((CMValue*) ba._buffer);
- ODDisposePtr(ba._buffer);
- valueSize = CMGetValueSize(value);
- CMDeleteValueData(value, 0, valueSize);
- SOM_CATCH_ALL
- SOM_ENDTRY
- _fCMContainer = kODNULL;
- }
- }
-
- return somSelf;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: GetCMContainer
- //------------------------------------------------------------------------------
-
- SOM_Scope CMContainer SOMLINK ODEmbeddedContainerGetCMContainer(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetCMContainer");
-
- return _fCMContainer;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: GetHandlers
- //------------------------------------------------------------------------------
-
- SOM_Scope ODBentoHandlers* SOMLINK ODEmbeddedContainerGetHandlers(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetHandlers");
-
- return _fHandlers;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: GetUseMode
- //------------------------------------------------------------------------------
-
- SOM_Scope CMContainerUseMode SOMLINK ODEmbeddedContainerGetUseMode(ODEmbeddedContainer *somSelf, Environment *ev)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetHandlers");
-
- return _fUseMode;
- }
-
- //------------------------------------------------------------------------------
- // ODEmbeddedContainer: SetMergeFlag
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODEmbeddedContainerSetMergeFlag(ODEmbeddedContainer *somSelf, Environment *ev,
- ODBoolean flag)
- {
- ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
- ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","SetMergeFlag");
-
- _fShouldMerge = flag;
- }
-
-